/*--------------------------------------------------------------------------
Example.c
****************************************
**  Copyright  (C)    2021-2022   **
**  Web:              http://rothd.cn   **
****************************************
--------------------------------------------------------------------------*/

//#include "../MC3172/MC3172.h"
#include "gpio.h"
#include "delay.h"
#include "uart.h"
#include "printf.h"
////////////////////////////////////////////////////////////

void GPIO_EXAMPLE(u32 gpio_sel)
{

#if 0
    INTDEV_SET_CLK_RST(gpio_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV2));
    GPIO_SET_OUTPUT_EN_VALUE(gpio_sel,(GPIO_PIN_ALL),GPIO_SET_ENABLE);
    GPIO_SET_OUTPUT_PIN_TO_0(gpio_sel,GPIO_PIN8);
    while(1)  {
        for (u32 var = 0; var < 500000; ++var) {
            NOP();
        }
        GPIO_SET_OUTPUT_PIN_INV(gpio_sel,GPIO_PIN8);
    }
#else
    u8 led_states;
    gpio_pin_init(GPIOD,8,OUTMODE,NOT_PULL);
    set_pin_value(GPIOD,8,VALUE_LOW);
    while(1)
    {
        //delay_us(2, 24);
       HAL_Delay(200);
       set_pin_value(GPIOD,8,!Get_Pin(GPIOD,8));
       //GPIO_SET_OUTPUT_PIN_INV(gpio_sel,GPIO_PIN8);

    }
#endif

}

////////////////////////////////////////////////////////////
//#define TEST_ONLY_UART_TX

void GPCOM_UART_EXAMPLE(u32 gpcom_sel)
{

#if 0
    INTDEV_SET_CLK_RST(gpcom_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV4));
    INTDEV_SET_CLK_RST(GPIOC,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV4));

    GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_RXD_IS_P2));
    GPCOM_SET_OUT_PORT(gpcom_sel,( \
            GPCOM_P0_OUTPUT_DISABLE|GPCOM_P3_OUTPUT_ENABLE|GPCOM_P2_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE| \
            GPCOM_P0_IS_HIGH       |GPCOM_P3_IS_TXD       |GPCOM_P2_IS_HIGH       |GPCOM_P1_IS_HIGH \
                      ));

    GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_UART_MODE);

    GPCOM_SET_COM_SPEED(gpcom_sel,6000000,115200);

    GPCOM_SET_OVERRIDE_GPIO(gpcom_sel, ( \
            GPCOM_P2_OVERRIDE_GPIO|GPCOM_P2_INPUT_ENABLE | \
            GPCOM_P3_OVERRIDE_GPIO \
                                              ));
#ifdef TEST_ONLY_UART_TX
    while(1){
        while(GPCOM_TX_FIFO_FULL(gpcom_sel));
        for (u32 var = 0; var < 90; ++var) {
            NOP();
        }
        GPCOM_PUSH_TX_DATA(gpcom_sel,'c');
    }

#else
    u8 rx_data_rp=0;
    u8 rx_data=0;
    rx_data_rp=GPCOM_GET_RX_WP(gpcom_sel);
    while(1) {
         if(rx_data_rp!=(GPCOM_GET_RX_WP(gpcom_sel))){
              rx_data=GPCOM_GET_RX_DATA(gpcom_sel,rx_data_rp);
              GPCOM_PUSH_TX_DATA(gpcom_sel,rx_data);
              rx_data_rp++;
              rx_data_rp&=0x0f;
         }
    }
#endif

#else
    u8 rx_data_rp;
#if 0

    u8 rx_data=0;
    uart_init(gpcom_sel,2,3,115200,&rx_data_rp);
    while(1)
    {
        UartReadData(&rx_data_rp,gpcom_sel,&rx_data,1);
        UartSendByte(gpcom_sel,rx_data);
    }
#else
    Print_init(gpcom_sel, 2, 3, 115200, &rx_data_rp);
    while(1)
    {
        printf("hello world");
        HAL_Delay(500);
    }

#endif
#endif
}





void GPCOM_SPI_EXAMPLE(u32 gpcom_sel)
{
    volatile u8 rx_data_temp[8];

    INTDEV_SET_CLK_RST(gpcom_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV2));

    GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_MASTER_IN_IS_P3));
    GPCOM_SET_OUT_PORT(gpcom_sel,( \
            GPCOM_P0_OUTPUT_ENABLE|GPCOM_P1_OUTPUT_ENABLE|GPCOM_P2_OUTPUT_ENABLE|GPCOM_P3_OUTPUT_DISABLE| \
            GPCOM_P0_IS_HIGH|      GPCOM_P1_IS_MASTER_CLK|GPCOM_P2_IS_MASTER_OUT|GPCOM_P3_IS_HIGH
                      ));

    GPCOM_SET_COM_MODE(gpcom_sel,(GPCOM_SPI_MASTER_MODE3|GPCOM_TX_MSB_FIRST|GPCOM_RX_MSB_FIRST));

    GPCOM_SET_COM_SPEED(gpcom_sel,24000000,1000000);

    GPCOM_SET_OVERRIDE_GPIO(gpcom_sel, ( \
            GPCOM_P0_OVERRIDE_GPIO| \
            GPCOM_P1_OVERRIDE_GPIO| \
            GPCOM_P2_OVERRIDE_GPIO| \
            GPCOM_P3_OVERRIDE_GPIO|GPCOM_P3_INPUT_ENABLE  \
                                              ));




    u8 tx_data_wp=0;
    u8 rx_data_rp=0;
    tx_data_wp=GPCOM_GET_TX_WP(gpcom_sel);
    rx_data_rp=GPCOM_GET_RX_WP(gpcom_sel);

    while(1){

        GPCOM_SET_OUT_PORT(gpcom_sel,( \
                GPCOM_P0_OUTPUT_ENABLE|GPCOM_P1_OUTPUT_ENABLE|GPCOM_P2_OUTPUT_ENABLE|GPCOM_P3_OUTPUT_DISABLE| \
                GPCOM_P0_IS_LOW|      GPCOM_P1_IS_MASTER_CLK| GPCOM_P2_IS_MASTER_OUT|GPCOM_P3_IS_HIGH
                          ));

        GPCOM_SEND_TX_DATA(gpcom_sel,tx_data_wp+0,CORE_CNT);
        GPCOM_SEND_TX_DATA(gpcom_sel,tx_data_wp+1,CORE_CNT);
        GPCOM_SEND_TX_DATA(gpcom_sel,tx_data_wp+2,CORE_CNT);
        GPCOM_SEND_TX_DATA(gpcom_sel,tx_data_wp+3,CORE_CNT);

        tx_data_wp+=4;
        GPCOM_SEND_TX_WP(gpcom_sel,tx_data_wp);
        while(!(GPCOM_TX_FIFO_EMPTY(gpcom_sel))){};




        while(rx_data_rp!=GPCOM_GET_RX_WP(gpcom_sel)){
            rx_data_temp[rx_data_rp&0x7]=GPCOM_GET_RX_DATA(gpcom_sel,rx_data_rp);
            rx_data_rp+=1;
            rx_data_rp&=0xf;

        };

        GPCOM_SET_OUT_PORT(gpcom_sel,( \
                GPCOM_P0_OUTPUT_ENABLE|GPCOM_P1_OUTPUT_ENABLE|GPCOM_P2_OUTPUT_ENABLE|GPCOM_P3_OUTPUT_DISABLE| \
                GPCOM_P0_IS_HIGH|      GPCOM_P1_IS_MASTER_CLK| GPCOM_P2_IS_MASTER_OUT|GPCOM_P3_IS_HIGH
                          ));
    }

}

void GPCOM_CAN_TX_EXAMPLE(u32 gpcom_sel)
{

    INTDEV_SET_CLK_RST(gpcom_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV4));

    GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_RXD_IS_P2));
    GPCOM_SET_OUT_PORT(gpcom_sel,( \
            GPCOM_P0_OUTPUT_DISABLE|GPCOM_P3_OUTPUT_ENABLE|GPCOM_P2_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE| \
            GPCOM_P0_IS_HIGH       |GPCOM_P3_IS_TXD       |GPCOM_P2_IS_HIGH       |GPCOM_P1_IS_HIGH \
                      ));

    GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_CAN_MODE);

    GPCOM_SET_COM_SPEED_ADV(gpcom_sel,12000000,1000000,3);
    GPCOM_SET_COM_DETIAL1(gpcom_sel,0x1f);

    GPCOM_SET_OVERRIDE_GPIO(gpcom_sel, ( \
            GPCOM_P2_OVERRIDE_GPIO|GPCOM_P2_INPUT_ENABLE | \
            GPCOM_P3_OVERRIDE_GPIO \
                                              ));


    while(1){
        GPCOM_SET_CANA_ID_RTR(gpcom_sel,0x220,0x0);
        GPCOM_SET_CANA_IDE_R0_DLC(gpcom_sel,0x0,0x0,0x8);
        GPCOM_SET_TX_WP(gpcom_sel,0x4);
        GPCOM_PUSH_CAN_DATA0(gpcom_sel,0x12);
        GPCOM_PUSH_CAN_DATA1(gpcom_sel,0x34);
        GPCOM_PUSH_CAN_DATA2(gpcom_sel,0x56);
        GPCOM_PUSH_CAN_DATA3(gpcom_sel,0x78);
        GPCOM_PUSH_CAN_DATA4(gpcom_sel,0x9a);
        GPCOM_PUSH_CAN_DATA5(gpcom_sel,0xbc);
        GPCOM_PUSH_CAN_DATA6(gpcom_sel,0xde);
        GPCOM_PUSH_CAN_DATA7(gpcom_sel,0xf0);
       while(1){

           if(GPCOM_TX_STATE(gpcom_sel)==GPCOM_CAN_TX_ARB_FAIL)break;
           if(GPCOM_TX_STATE(gpcom_sel)==GPCOM_CAN_TX_DONE)break;
           if(GPCOM_TX_STATE(gpcom_sel)==GPCOM_CAN_TX_ERROR)break;

       }


           if((GPCOM_RX_STATE(gpcom_sel))==GPCOM_CAN_RX_ERROR){
               GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_CAN_MODE|0x10);
               GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_CAN_MODE);
           }
           if((GPCOM_RX_STATE(gpcom_sel))==GPCOM_CAN_RX_OVERLOAD){
               GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_CAN_MODE|0x10);
               GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_CAN_MODE);
           }





       GPCOM_SET_TX_WP(gpcom_sel,0x0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }

    }

}

////////////////////////////////////////////////////////////



void GPCOM_CAN_RX_EXAMPLE(u32 gpcom_sel)
{


    INTDEV_SET_CLK_RST(gpcom_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV4));

    GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_RXD_IS_P2));
    GPCOM_SET_OUT_PORT(gpcom_sel,( \
            GPCOM_P0_OUTPUT_DISABLE|GPCOM_P3_OUTPUT_ENABLE|GPCOM_P2_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE| \
            GPCOM_P0_IS_HIGH       |GPCOM_P3_IS_TXD       |GPCOM_P2_IS_HIGH       |GPCOM_P1_IS_HIGH \
                      ));

    GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_CAN_MODE);

    GPCOM_SET_COM_SPEED_ADV(gpcom_sel,12000000,1000000,3);
    GPCOM_SET_COM_DETIAL1(gpcom_sel,0x1f);





    GPCOM_SET_OVERRIDE_GPIO(gpcom_sel, ( \
            GPCOM_P2_OVERRIDE_GPIO|GPCOM_P2_INPUT_ENABLE | \
            GPCOM_P3_OVERRIDE_GPIO \
                                              ));

   volatile u8 rx_info[3];

   volatile u8 rx_data[8];


       while(1){
           while(GPCOM_GET_RX_WP(gpcom_sel)>3);
           GPCOM_GET_CANA_ID_RTR(gpcom_sel,rx_info[0]);
           GPCOM_GET_CANA_IDE_R0_DLC(gpcom_sel,rx_info[1]);
           //if(need_ack)    GPCOM_SET_COM_DETIAL2(gpcom_sel,0x1);
           GPCOM_SET_COM_DETIAL2(gpcom_sel,0x1);
           //else      GPCOM_SET_COM_DETIAL2(gpcom_sel,0x0);
           while(GPCOM_GET_RX_WP(gpcom_sel)>4);
           GPCOM_GET_CAN_DATA0(gpcom_sel,rx_data[0]);
           while(GPCOM_GET_RX_WP(gpcom_sel)>5);
           GPCOM_GET_CAN_DATA1(gpcom_sel,rx_data[1]);
           while(GPCOM_GET_RX_WP(gpcom_sel)>6);
           GPCOM_GET_CAN_DATA2(gpcom_sel,rx_data[2]);
           while(GPCOM_GET_RX_WP(gpcom_sel)>7);
           GPCOM_GET_CAN_DATA3(gpcom_sel,rx_data[3]);
           while(1){

               if((GPCOM_RX_STATE(gpcom_sel))==GPCOM_CAN_RX_ERROR){
                   GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_CAN_MODE|0x10);
                   GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_CAN_MODE);break;
               }
               if((GPCOM_RX_STATE(gpcom_sel))==GPCOM_CAN_RX_DONE)break;
               if((GPCOM_RX_STATE(gpcom_sel))==GPCOM_CAN_RX_OVERLOAD)break;

           }
           GPCOM_SET_COM_DETIAL2(gpcom_sel,0x0);



       }


}


void GPCOM_USB_TX_EXAMPLE(u32 gpcom_sel)
{

    INTDEV_SET_CLK_RST(gpcom_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK));
    
    GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_LSDP_IS_P2|GPCOM_LSDM_IS_P3));
    GPCOM_SET_OUT_PORT(gpcom_sel,( \
            GPCOM_P0_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE|GPCOM_P2_OUTPUT_USBDP |GPCOM_P2_OUTPUT_USBDM| \
            GPCOM_P0_IS_HIGH       |GPCOM_P1_IS_HIGH       |GPCOM_P2_IS_LSDP        |GPCOM_P3_IS_LSDM \
                      ));

    //GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_FSDP_IS_P2|GPCOM_FSDM_IS_P3));
    //GPCOM_SET_OUT_PORT(gpcom_sel,( \
    //        GPCOM_P0_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE|GPCOM_P2_OUTPUT_USBDP |GPCOM_P2_OUTPUT_USBDM| \
    //        GPCOM_P0_IS_HIGH       |GPCOM_P1_IS_HIGH       |GPCOM_P2_IS_FSDP        |GPCOM_P3_IS_FSDM \
    //                  ));

    GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_USB_MODE);

    //GPCOM_SET_COM_SPEED_ADV(gpcom_sel,48000000,12000000,0);
    GPCOM_SET_COM_SPEED_ADV(gpcom_sel,48000000,1500000,0);
    //GPCOM_SET_COM_DETIAL1(gpcom_sel,0x1f);

    GPCOM_SET_OVERRIDE_GPIO(gpcom_sel, ( \
            GPCOM_P2_OVERRIDE_GPIO|GPCOM_P2_INPUT_ENABLE | \
            GPCOM_P3_OVERRIDE_GPIO|GPCOM_P3_INPUT_ENABLE \
                                              ));
    //GPCOM_SET_USB_ASSIGNED_ADDR(gpcom_sel,0x0);
    GPCOM_SET_COM_DETIAL2(gpcom_sel,0x0);

        u8 tx_data_wp=0;
        u8 rx_data_rp=0;
        GPCOM_SET_TX_WP(gpcom_sel,0);
    while(1)
    {
/////////////////////////////////////////////////////////////////
    //send usb frame


        GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_SOF);
        GPCOM_PUSH_USB_INFO(gpcom_sel,0x3db);
        while(GPCOM_TX_STATE(gpcom_sel)!=GPCOM_USB_TX_DONE);
        GPCOM_SET_TX_WP(gpcom_sel,0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }

        GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_IN);
        GPCOM_PUSH_USB_ADDR_ENDP(gpcom_sel,1,2);
        while(GPCOM_TX_STATE(gpcom_sel)!=GPCOM_USB_TX_DONE);
        GPCOM_SET_TX_WP(gpcom_sel,0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }



        GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_OUT);
        GPCOM_PUSH_USB_ADDR_ENDP(gpcom_sel,1,1);
        while(GPCOM_TX_STATE(gpcom_sel)!=GPCOM_USB_TX_DONE);
        GPCOM_SET_TX_WP(gpcom_sel,0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }




        GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_SETUP);
        GPCOM_PUSH_USB_ADDR_ENDP(gpcom_sel,1,0);
        while(GPCOM_TX_STATE(gpcom_sel)!=GPCOM_USB_TX_DONE);
        GPCOM_SET_TX_WP(gpcom_sel,0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }

////////////////////////////////////////////////////////////////////

        GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_DATA0);
        //GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_DATA1);
        GPCOM_SET_TX_WP(gpcom_sel,4);
        tx_data_wp=32;
        GPCOM_PUSH_USB_DATA(gpcom_sel,tx_data_wp,0x31);
        tx_data_wp+=8;
        GPCOM_PUSH_USB_DATA(gpcom_sel,tx_data_wp,0x32);
        tx_data_wp+=8;
        GPCOM_PUSH_USB_DATA(gpcom_sel,tx_data_wp,0x0d);
        tx_data_wp+=8;
        GPCOM_PUSH_USB_DATA(gpcom_sel,tx_data_wp,0x0a);
        tx_data_wp+=8;
        while(GPCOM_TX_FIFO_FULL(gpcom_sel));
        GPCOM_PUSH_USB_DATA(gpcom_sel,tx_data_wp,0xa8);
        tx_data_wp+=8;
        while(GPCOM_TX_FIFO_FULL(gpcom_sel));
        GPCOM_PUSH_USB_DATA(gpcom_sel,tx_data_wp,0xa9);
        tx_data_wp+=8;
        while(GPCOM_TX_FIFO_FULL(gpcom_sel));
        GPCOM_PUSH_USB_DATA(gpcom_sel,tx_data_wp,0xaa);
        tx_data_wp+=8;
        while(GPCOM_TX_FIFO_FULL(gpcom_sel));
        GPCOM_PUSH_USB_DATA(gpcom_sel,tx_data_wp,0xab);

        while(GPCOM_TX_STATE(gpcom_sel)!=GPCOM_USB_TX_DONE);
        GPCOM_SET_TX_WP(gpcom_sel,0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }

        //GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_DATA0);
        GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_DATA1);
        GPCOM_SET_TX_WP(gpcom_sel,2);
        while(GPCOM_TX_STATE(gpcom_sel)!=GPCOM_USB_TX_DONE);
        GPCOM_SET_TX_WP(gpcom_sel,0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }



////////////////////////////////////////////////////////////////////


        GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_ACK);
        while(GPCOM_TX_STATE(gpcom_sel)!=GPCOM_USB_TX_DONE);
        GPCOM_SET_TX_WP(gpcom_sel,0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }



        GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_NAK);
        while(GPCOM_TX_STATE(gpcom_sel)!=GPCOM_USB_TX_DONE);
        GPCOM_SET_TX_WP(gpcom_sel,0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }


        GPCOM_PUSH_USB_PID(gpcom_sel,GPCOM_USB_PID_STALL);
        while(GPCOM_TX_STATE(gpcom_sel)!=GPCOM_USB_TX_DONE);
        GPCOM_SET_TX_WP(gpcom_sel,0);
        for (u32 var = 0; var < 500; ++var) {
            NOP();
        }






    }

}

////////////////////////////////////////////////////////////

u8 rx_data[70];

void GPCOM_USB_RX_EXAMPLE(u32 gpcom_sel)
{


    INTDEV_SET_CLK_RST(gpcom_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK));

    GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_LSDP_IS_P2|GPCOM_LSDM_IS_P3));
    GPCOM_SET_OUT_PORT(gpcom_sel,( \
            GPCOM_P0_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE|GPCOM_P2_OUTPUT_USBDP |GPCOM_P2_OUTPUT_USBDM| \
            GPCOM_P0_IS_HIGH       |GPCOM_P1_IS_HIGH       |GPCOM_P2_IS_LSDP        |GPCOM_P3_IS_LSDM \
                      ));

    //GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_FSDP_IS_P2|GPCOM_FSDM_IS_P3));
    //GPCOM_SET_OUT_PORT(gpcom_sel,( \
    //        GPCOM_P0_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE|GPCOM_P2_OUTPUT_USBDP |GPCOM_P2_OUTPUT_USBDM| \
    //        GPCOM_P0_IS_HIGH       |GPCOM_P1_IS_HIGH       |GPCOM_P2_IS_FSDP        |GPCOM_P3_IS_FSDM \
    //                  ));

    GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_USB_MODE);

//    GPCOM_SET_COM_SPEED_ADV(gpcom_sel,48000000,12000000,0);
    GPCOM_SET_COM_SPEED_ADV(gpcom_sel,48000000,1500000,0);

    GPCOM_SET_OVERRIDE_GPIO(gpcom_sel, ( \
            GPCOM_P2_OVERRIDE_GPIO|GPCOM_P2_INPUT_ENABLE | \
            GPCOM_P3_OVERRIDE_GPIO|GPCOM_P3_INPUT_ENABLE \
                                              ));
    GPCOM_SET_COM_DETIAL2(gpcom_sel,0x0);



   u8 rx_pid;
   u16 rx_info;


   u8 rx_rp;
   u8 rx_crc_err;

   while(GPCOM_USB_RX_STATE(gpcom_sel)!=0);

       while(1){

           rx_rp=4;
           while(GPCOM_GET_RX_WP(gpcom_sel)<=1);
           rx_pid=GPCOM_USB_RX_PID(gpcom_sel);
           if(rx_pid==GPCOM_USB_PID_IN){
               while(GPCOM_GET_RX_WP(gpcom_sel)<=2);
               rx_info=GPCOM_USB_RX_INFO(gpcom_sel);
               while(GPCOM_GET_RX_WP(gpcom_sel)==3);
               rx_crc_err = ((GPCOM_GET_RX_DATA(gpcom_sel,3))&0x1f) != (GPCOM_USB_RX_CRC5(gpcom_sel));

           }
           else if((rx_pid==GPCOM_USB_PID_DATA0)|(rx_pid==GPCOM_USB_PID_DATA1)){

               while(1)
               {
                   while(GPCOM_GET_RX_WP(gpcom_sel)==4);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,4);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==5);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,5);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==6);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,6);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==7);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,7);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==8);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,0);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==9);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,1);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==10);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,2);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==11);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,3);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==12);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,4);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==13);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,5);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==14);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,6);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==15);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,7);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==0);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,0);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==1);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,1);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==2);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,2);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;
                   while(GPCOM_GET_RX_WP(gpcom_sel)==3);
                   rx_data[rx_rp]=GPCOM_GET_RX_DATA(gpcom_sel,3);
                   rx_rp++;
                   if(GPCOM_USB_RX_STATE(gpcom_sel)!=GPCOM_USB_RX_DATA_STATE)break;




               }

               rx_data[0]=rx_pid;
               rx_data[1]=rx_rp;
               rx_crc_err = (rx_data[rx_rp-1]<<8+rx_data[rx_rp-2])!=GPCOM_USB_RX_CRC16(gpcom_sel);

           }
           else if((rx_pid==GPCOM_USB_PID_OUT)|(rx_pid==GPCOM_USB_PID_SETUP)){
               while(GPCOM_GET_RX_WP(gpcom_sel)<=2);
               rx_info=GPCOM_USB_RX_INFO(gpcom_sel);
               while(GPCOM_GET_RX_WP(gpcom_sel)==3);
               rx_crc_err = ((GPCOM_GET_RX_DATA(gpcom_sel,3))&0x1f) != (GPCOM_USB_RX_CRC5(gpcom_sel));
           }
           else if(rx_pid==GPCOM_USB_PID_SOF){
               while(GPCOM_GET_RX_WP(gpcom_sel)<=2);
               rx_info=GPCOM_USB_RX_INFO(gpcom_sel);
               while(GPCOM_GET_RX_WP(gpcom_sel)==3);
               rx_crc_err = ((GPCOM_GET_RX_DATA(gpcom_sel,3))&0x1f) != (GPCOM_USB_RX_CRC5(gpcom_sel));
           }
           while(GPCOM_USB_RX_STATE(gpcom_sel)!=0);


       }


}



void TIMER_COMPARER_EXAMPLE(u32 timer_sel)
{


    INTDEV_SET_CLK_RST(timer_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK));


    TIMER_SET_OVERRIDE_GPIO(timer_sel,(
                                       TIMER_P3_OVERRIDE_GPIO|TIMER_P3_PULL_UP| \
                                       TIMER_P2_OVERRIDE_GPIO| \
                                       TIMER_P1_OVERRIDE_GPIO| \
                                       TIMER_P0_OVERRIDE_GPIO) \
                           );



    TIMER_SET_OUTPUT_EN(timer_sel,(TIMER_P0_OUTPUT_ENABLE |TIMER_P1_OUTPUT_ENABLE |TIMER_P2_OUTPUT_ENABLE |TIMER_P3_OUTPUT_ENABLE| \
                                   TIMER_P4_OUTPUT_DISABLE|TIMER_P5_OUTPUT_DISABLE|TIMER_P6_OUTPUT_DISABLE|TIMER_P7_OUTPUT_DISABLE));


    TIMER_SET_OUT_PORT(timer_sel,(TIMER_P0_IS_COMPARER0|TIMER_P1_IS_COMPARER1|TIMER_P3_IS_COMPARER2|TIMER_P2_IS_COMPARER3));

    TIMER_SET_COMPARER_MODE(timer_sel,(TIMER_COMPARER3_NOT_FORCE|TIMER_COMPARER2_NOT_FORCE|TIMER_COMPARER1_NOT_FORCE|TIMER_COMPARER0_NOT_FORCE));

    TIMER_SET_MAIN_CNT_BEGIN_VALUE0(timer_sel,TIMER_MAIN_CNT_COUNT_UP,0x00000000);
    TIMER_SET_MAIN_CNT_END_VALUE0(timer_sel,0x1000);
    TIMER_SET_MAIN_CNT_BEGIN_VALUE1(timer_sel,TIMER_MAIN_CNT_COUNT_DOWN,0x00008000);
    TIMER_SET_MAIN_CNT_END_VALUE1(timer_sel,0x00007000);
    TIMER_SET_CMD(timer_sel,TIMER_CMD_RESTART);



    TIMER_SET_COMPARER0_VALUE0_0(timer_sel,TIMER_COMPARER_OUTPUT0,0xf2);
    TIMER_SET_COMPARER0_VALUE0_1(timer_sel,TIMER_COMPARER_OUTPUT1,0x1f2);
    TIMER_SET_COMPARER0_VALUE1_0(timer_sel,TIMER_COMPARER_OUTPUT0,0x7777);
    TIMER_SET_COMPARER0_VALUE1_1(timer_sel,TIMER_COMPARER_OUTPUT1,0x7666);

    TIMER_SET_COMPARER1_VALUE0_0(timer_sel,TIMER_COMPARER_INV,0x1e4);
    TIMER_SET_COMPARER1_VALUE0_1(timer_sel,TIMER_COMPARER_HOLD,0x553);
    TIMER_SET_COMPARER1_VALUE1_0(timer_sel,TIMER_COMPARER_INV,0x7291);
    TIMER_SET_COMPARER1_VALUE1_1(timer_sel,TIMER_COMPARER_HOLD,0x327);

    TIMER_SET_COMPARER2_VALUE0_0(timer_sel,TIMER_COMPARER_OUTPUT0,0x202);
    TIMER_SET_COMPARER2_VALUE0_1(timer_sel,TIMER_COMPARER_INV,0x303);
    TIMER_SET_COMPARER2_VALUE1_0(timer_sel,TIMER_COMPARER_OUTPUT0,0x189);
    TIMER_SET_COMPARER2_VALUE1_1(timer_sel,TIMER_COMPARER_INV,0x377);

    TIMER_SET_COMPARER3_VALUE0_0(timer_sel,TIMER_COMPARER_OUTPUT0,0xf12);
    TIMER_SET_COMPARER3_VALUE0_1(timer_sel,TIMER_COMPARER_OUTPUT1,0x733);
    TIMER_SET_COMPARER3_VALUE1_0(timer_sel,TIMER_COMPARER_INV,0x7569);
    TIMER_SET_COMPARER3_VALUE1_1(timer_sel,TIMER_COMPARER_INV,0x7227);

    TIMER_SET_CMD(timer_sel,TIMER_CMD_RUN);
    while(1);
}


void TIMER_CAPTURER_EXAMPLE(u32 timer_sel)
{



    INTDEV_SET_CLK_RST(timer_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK));


    TIMER_SET_OUTPUT_EN(timer_sel,(TIMER_P0_OUTPUT_ENABLE|TIMER_P1_OUTPUT_ENABLE|TIMER_P2_OUTPUT_ENABLE|TIMER_P3_OUTPUT_ENABLE| \
                                   TIMER_P4_OUTPUT_DISABLE|TIMER_P5_OUTPUT_DISABLE|TIMER_P6_OUTPUT_DISABLE|TIMER_P7_OUTPUT_DISABLE));


    TIMER_SET_IN_PORT(timer_sel,(TIMER_CAPTURER0_IS_P7|TIMER_CAPTURER1_IS_P5|TIMER_CAPTURER2_IS_P6|TIMER_CAPTURER3_IS_P4));
    //TIMER_SET_OUT_PORT(timer_sel,(TIMER_P0_IS_COMPARER0|TIMER_P1_IS_COMPARER1|TIMER_P3_IS_COMPARER2|TIMER_P2_IS_COMPARER3));


    TIMER_SET_OVERRIDE_GPIO(timer_sel,(TIMER_P7_OVERRIDE_GPIO|TIMER_P7_INPUT_ENABLE|TIMER_P7_PULL_UP| \
                                       TIMER_P6_OVERRIDE_GPIO|TIMER_P6_INPUT_ENABLE| \
                                       TIMER_P5_OVERRIDE_GPIO|TIMER_P5_INPUT_ENABLE| \
                                       TIMER_P4_OVERRIDE_GPIO|TIMER_P4_INPUT_ENABLE \
                                      )
                            );



    //TIMER_SET_COMPARER_MODE(timer_sel,(TIMER_COMPARER3_NOT_FORCE|TIMER_COMPARER2_NOT_FORCE|TIMER_COMPARER1_NOT_FORCE|TIMER_COMPARER0_NOT_FORCE));

    TIMER_SET_MAIN_CNT_BEGIN_VALUE0(timer_sel,TIMER_MAIN_CNT_COUNT_UP,0x00000000);
    TIMER_SET_MAIN_CNT_END_VALUE0(timer_sel,0x00100000);
    TIMER_SET_MAIN_CNT_BEGIN_VALUE1(timer_sel,TIMER_MAIN_CNT_COUNT_UP,0x00e00000);
    TIMER_SET_MAIN_CNT_END_VALUE1(timer_sel,0x00f00000);
    TIMER_SET_CMD(timer_sel,TIMER_CMD_RESTART);


    TIMER_SET_CAPTURER_MODE(timer_sel,(TIMER_CAPTURER0_FILTER_ENABLE|TIMER_CAPTURER0_RISING_EDGE|TIMER_CAPTURER0_FALLING_EDGE|TIMER_CAPTURER1_RISING_EDGE|TIMER_CAPTURER3_FALLING_EDGE));




    u8 capturer0_data_rp=0;
    u8 capturer1_data_rp=0;
    u8 capturer2_data_rp=0;
    u8 capturer3_data_rp=0;

    capturer0_data_rp=TIMER_GET_CAPTURE0_WP(timer_sel);
    capturer1_data_rp=TIMER_GET_CAPTURE1_WP(timer_sel);
    capturer2_data_rp=TIMER_GET_CAPTURE2_WP(timer_sel);
    capturer3_data_rp=TIMER_GET_CAPTURE3_WP(timer_sel);


    volatile u32 capturer0_data_temp[8];
    volatile u32 capturer1_data_temp[8];
    volatile u32 capturer2_data_temp[8];
    volatile u32 capturer3_data_temp[8];

    TIMER_SET_CMD(timer_sel,TIMER_CMD_RUN);

    while(1){
        if((capturer0_data_rp&0x1)!=TIMER_GET_CAPTURE0_WP(timer_sel)){
            capturer0_data_temp[capturer0_data_rp]=TIMER_GET_CAPTURE0_VALUE(timer_sel,capturer0_data_rp);
            capturer0_data_rp++;
            capturer0_data_rp&=0x7;
        }
        if((capturer1_data_rp&0x1)!=TIMER_GET_CAPTURE1_WP(timer_sel)){
            capturer1_data_temp[capturer1_data_rp]=TIMER_GET_CAPTURE1_VALUE(timer_sel,capturer1_data_rp);
            capturer1_data_rp++;
            capturer1_data_rp&=0x7;
        }
        if((capturer2_data_rp&0x1)!=TIMER_GET_CAPTURE2_WP(timer_sel)){
            capturer2_data_temp[capturer2_data_rp]=TIMER_GET_CAPTURE2_VALUE(timer_sel,capturer2_data_rp);
            capturer2_data_rp++;
            capturer2_data_rp&=0x7;
        }
        if((capturer3_data_rp&0x1)!=TIMER_GET_CAPTURE3_WP(timer_sel)){
            capturer3_data_temp[capturer3_data_rp]=TIMER_GET_CAPTURE3_VALUE(timer_sel,capturer3_data_rp);
            capturer3_data_rp++;
            capturer3_data_rp&=0x7;
        }
    }



}

////////////////////////////////////////////////////////////



